if not menu then menu = {} end

if not menu.label then


dofile (getScriptPath() .. "\\..\\lib\\lib.lua")


menu.label = {price = {},
	ini = lib.path.init .. "labels.ini",
	prices = {"tp", "lm", "sl", "sev", "tev"},
	show = {"tp", "lm", "sl"},		-- show in table
	fmt = {tp = "%s [SET]", sl = "%s [SET]"},		-- format in table
	rgb = {tp = {R = 128, G = 255, B = 128},
		lm = {R = 128, G = 128, B = 255},
		sl = {R = 255, G = 128, B = 128},
		sev = {R = 64, G = 128, B = 128},
		tev = {R = 64, G = 128, B = 64}
	},
	yvalue = {
		lm =		function(low, high, is_long, candle)
						if is_long then
							return candle.low
						end
						return candle.high
					end,
		sl = 		function(low, high, is_long, candle)
						if is_long then
							return menu.label.yvalue.lm(low, high, is_long, candle) * 0.997
						end
						return menu.label.yvalue.lm(low, high, is_long, candle) * 1.003
					end,
		tp = 		function(low, high, is_long, candle)
						if is_long then
							return menu.label.yvalue.lm(low, high, is_long, candle) * 1.01
						end
						return menu.label.yvalue.lm(low, high, is_long, candle) * 0.99
					end
	},
	loaded = 0,
	changed = {}
}


processor:AddInit(function()
	for i, v in ipairs(menu.label.prices) do
		menu.label.prices[v] = {index = i}
	end
end)


processor:AddInit(function()
	window:AddRow()
	menu.label.rows = 0
	
	for i, v in ipairs(menu.label.show) do
		menu.label.show[v] = {index = i, row = window:AddRow()}
		
		if not menu.label.row then
			menu.label.row = menu.label.show[v].row
		end
		
		menu.label.rows = menu.label.rows + 1
		window:SetCell(menu.label.show[v].row, 1, string.upper(v))
	end
end)
	
	
processor:AddHandler("OnTableNotification", function(data)
	if data.msg == 11 and data.par1 >= menu.label.row
		and data.par1 < menu.label.row + menu.label.rows
		and data.par2 == 1
	then
		menu.label:Remove()
	end
end)


processor:AddTimer(function()
	if menu.chart.changed.selected then
		menu.label.price = {}
	end
end)


processor:AddTimer(function()
	if menu.label.do_limit then
		if orders:GetPosition(menu.label.do_limit, false) ~= 0 then
			menu.action:Limit()
		end
		
		menu.label.do_limit = nil
	end
end)


processor:AddTimer(function()
	local labels = lib:LoadLabels(menu.chart.instrument.code)
	
	if labels and menu.label.loaded ~= labels.seconds_ then
		menu.label.loaded = labels.seconds_
		if (menu.label.price.lm
			and labels.lm
			and math.abs(menu.label.price.lm - tonumber(labels.lm)) >= menu.chart.instrument.min_price_step)
			or (menu.label.price.sl
			and labels.sl
			and math.abs(menu.label.price.sl - tonumber(labels.sl)) >= menu.chart.instrument.min_price_step)
		then
			menu.label.do_limit = menu.chart.instrument.code
		end
	else
		labels = nil
	end
	
	if menu.chart.changed.instrument or labels then
		menu.label:Remove(labels)
	end
end)


processor:AddTimer(function()
	local found
	
	repeat
		found = menu.label:Find()
		
		for i, v in ipairs(menu.label.prices) do
			if menu.label.price[v] ~= found[v] then
				if menu.label.price[v] and found[v] then
					menu.label.changed[v] = found[v] - menu.label.price[v]
				else
					menu.label.changed[v] = 0
				end
			end
		end
		
		menu.label.price = found
	until not menu.label:Create()
end)

processor:AddTimer(function()
	if menu.label.price.lm and menu.label.price.sl then
		if menu.label.price.lm > menu.label.price.sl then
			menu.label.long = true
		else
			menu.label.long = false
		end
	else
		menu.label.long = nil
	end
end)


processor:AddTimer(function()
	if menu.label.price.tp
		and (menu.label.long == nil
			or not menu.label.price.lm
			or menu.label.long and menu.label.price.lm >= menu.label.price.tp
			or not menu.label.long and menu.label.price.lm <= menu.label.price.tp
		)
	then
		menu.label.price.tp = nil
	end
end)


processor:AddTimer(function()
	for i, v in ipairs(menu.label.prices) do
		if menu.label.changed[v] then
			if menu.label.show[v] then
				if menu.label.price[v] then
					window:SetCell(menu.label.show[v].row, 2, string.format(menu.label.fmt[v] or "%s", tostring(menu.label.price[v])))
				else
					window:SetCell(menu.label.show[v].row, 2, "")
				end
			end
		end
	end
end)


function menu.label:Find()
	local found = {}
	local lp
	
	for i = lib:GetMaxLabelID(menu.chart.tag) * 2, 0, -1 do
		lp = GetLabelParams(menu.chart.tag, i)
		
		if lp and lp.yvalue then
			for _, v in ipairs(menu.label.prices) do
				if string.match(lp.text, "^" .. v) then
					if found[v] then
						DelLabel(menu.chart.tag, i)
					else
						found[v] = lib:NormalizePrice(lp.yvalue, menu.chart.instrument)
					end
				end
			end
		end
	end
	
	return found
end


function menu.label:Remove(text)
	if type(text) == "string" then
		if menu.label.prices[text] then
			local lp
			
			for i = lib:GetMaxLabelID(menu.chart.tag) * 2, 0, -1 do
				lp = GetLabelParams(menu.chart.tag, i)
				
				if lp and lp.yvalue
					and string.match(lp.text, "^" .. text)
				then
					DelLabel(menu.chart.tag, i)
				end
			end
		end
	else
		local lp
		
		for i = lib:GetMaxLabelID(menu.chart.tag) * 2, 0, -1 do
			lp = GetLabelParams(menu.chart.tag, i)
			
			if lp and lp.yvalue then
				for _, v in ipairs(menu.label.prices) do
					if string.match(lp.text, "^" .. v) then
						DelLabel(menu.chart.tag, i)
						
						break
					end
				end
			end
		end
		
		self:Load(text)
	end
end


function menu.label:Create(text, price)
	if text then
		if menu.label.prices[text] then
			local candle = lib:GetLastCandle(menu.chart.tag, 3)
			
			if candle then
				if price then
					self:Remove(text)
				end
			
				local label_params = self.rgb[text]
				
				if not label_params then
					label_params = {R = 128, G = 128, B = 128}
				end
				
				label_params.TRANSPARENT_BACKGROUND = 1
				label_params.TEXT = text
				label_params.DATE = candle.datetime.year * 10000 + candle.datetime.month * 100 + candle.datetime.day
				label_params.TIME = candle.datetime.hour * 10000 + candle.datetime.min * 100 + candle.datetime.sec
				
				if price then
					label_params.YVALUE = tonumber(price)
					label_params.HINT = tostring(label_params.YVALUE)
				elseif self.yvalue[text] then
					local low, high, is_long = lib:GetCandleRange(menu.chart.tag, 1, 30)
					candle = lib:GetLastCandle(menu.chart.tag)
					if candle and low then
						label_params.YVALUE = self.yvalue[text](low, high, is_long, candle)
					end
				end
				
				if not label_params.YVALUE then
					label_params.YVALUE = candle.close * (1 + (
						bit.band(label_params.G, 192) +
						bit.band(label_params.B, 192) / 4 +
						bit.band(label_params.R, 192) / 16 - 192) / 10000)
				end
				
				if label_params.YVALUE > candle.close * 2 then
					label_params.YVALUE = candle.close * 2
				end
				
				lib:AddLabel(menu.chart.tag, label_params)
				
				return true
			end
		end
	else
		local ret
		
		for _, v in ipairs(menu.label.prices) do
			if not menu.label.price[v] then
				if self:Create(v) then
					ret = true
				end
			end
		end
		
		return ret
	end
end


function menu.label:Load(param)
	if menu.chart.instrument then
		local labels = param
		
		if type(labels) ~= "table" then
			labels = lib:LoadLabels(menu.chart.instrument.code)
			message("Load Labels " .. lib:toline(param) .. " " .. lib:toline(menu.chart.instrument.code) .. " " .. lib:toline(labels))
		end
		
		if not labels then
			local save = true
			local hf = io.open(menu.label.ini, "r")
			
			if hf then
				local date = hf:read()
				
				if date == lib:FormatDate() then
					save = false
					local str = hf:read()
					while str do
						str = split(str)
						if #str > 0 and str[1] == menu.chart.instrument.code then
							labels = {}
							if #str >= 2 then labels.lm = str[2] end
							if #str >= 3 then labels.sl = str[3] end
							if #str >= 4 then labels.tp = str[4] end
							break
						end
						str = hf:read()
					end
				elseif date > lib:FormatDate() then
					save = false
				end
				
				hf:close()
			end
			
			if save then
				hf = io.open(menu.label.ini, "w")
				
				if hf then
					hf:write(lib:FormatDate() .. "\n")
					hf:write("TICKER LM SL TP\n")
					hf:close()
				end
			end
		end
		
		if labels then
			local sl, lm
			if labels.sl then sl = tonumber(labels.sl) end
			if labels.lm then lm = tonumber(labels.lm) end
			
			for k, v in pairs(labels) do
				self:Create(k, v)
			end
		end
	end
end


end -- of file
